package com.dikeleakagedetection.myapplication.ui.database

import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.MediaStore
import android.view.View
import android.view.ViewGroup
import android.widget.Toast

import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import cn.leancloud.AVObject
import com.dikeleakagedetection.myapplication.DikeLeakageDetectionApp
import com.dikeleakagedetection.myapplication.databinding.ActTabletBinding
import com.dikeleakagedetection.myapplication.logic.dao.Dot

import com.dikeleakagedetection.myapplication.logic.dao.AppDatabase
import com.dikeleakagedetection.myapplication.logic.dao.Tablet
import com.dikeleakagedetection.myapplication.utils.showToast
import com.yanzhenjie.recyclerview.SwipeMenuItem
import java.io.BufferedOutputStream
import kotlin.concurrent.thread

class TabletActivity : AppCompatActivity() {
    private lateinit var binding: ActTabletBinding

    private lateinit var tablet:Tablet

    private var flagFabMenu = false

    private val dotList by lazy {
        ArrayList<Dot>()
    }

    private val dotDao by lazy {
        AppDatabase.getDatabase(DikeLeakageDetectionApp.context).dotDao()
    }

    private val tabletDao by lazy {
        AppDatabase.getDatabase(DikeLeakageDetectionApp.context).tabletDao()
    }

    private val dotAdapter by lazy {
        DotAdapter(this, dotList)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActTabletBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val tabletId = intent.getLongExtra("tablet_id", 0)
        initData(tabletId)
    }

    private fun initView(tablet: Tablet) {
        binding.tvTabletIdActTablet.text = tablet.id.toString()
        binding.tvTabletPlaceActTablet.text = tablet.place
        binding.tvTabletDateActTablet.text = tablet.date
        binding.tvTabletLengthActTablet.text = tablet.length.toString()
        binding.tvTabletWidthActTablet.text = tablet.width.toString()

        initAdapter()

        initListener()
    }

    private fun initListener() {
        binding.fabMenuActTablet.setOnClickListener {
            if(flagFabMenu){
                binding.fabDocActTablet.visibility = View.GONE
                binding.fabContourMapActTablet.visibility = View.GONE
                binding.fabUploadActTablet.visibility = View.GONE
                flagFabMenu = false
            }else {
                binding.fabDocActTablet.visibility = View.VISIBLE
                binding.fabContourMapActTablet.visibility = View.VISIBLE
                binding.fabUploadActTablet.visibility = View.VISIBLE
                flagFabMenu = true
            }
        }

        binding.fabDocActTablet.setOnClickListener {
            writeInputStreamToFile()//导出文件并分享
        }

        binding.fabContourMapActTablet.setOnClickListener {
            val dialog = ContourMapDialogFragment()
            dialog.showNow(supportFragmentManager, "ContourMapDialogFragment")
        }

        binding.fabUploadActTablet.setOnClickListener {
            uploadData()
        }
    }

    private fun uploadData() {
        if(tablet.userId == null){
            "请登录".showToast()
            return
        }
        val avObjectList = ArrayList<AVObject>()
        val tabletCloud = AVObject("TabletCloud")
        tabletCloud.put("place", tablet.place)
        tabletCloud.put("date", tablet.date)
        tabletCloud.put("length", tablet.length)
        tabletCloud.put("width", tablet.width)
        tabletCloud.put("userId", tablet.userId)
        avObjectList.add(tabletCloud)

        for(dot in dotList){
            val dotCloud = AVObject("DotCloud")
            dotCloud.put("magneticX", dot.magneticX)
            dotCloud.put("magneticY", dot.magneticY)
            dotCloud.put("magneticZ", dot.magneticZ)
            dotCloud.put("attitudeX", dot.attitudeX)
            dotCloud.put("attitudeY", dot.attitudeY)
            dotCloud.put("attitudeZ", dot.attitudeZ)
            dotCloud.put("locationLng", dot.locationLng)
            dotCloud.put("locationLat", dot.locationLat)
            dotCloud.put("locationAlt", dot.locationAlt)
            dotCloud.put("tabletId", dot.tabletId)
            avObjectList.add(dotCloud)
        }

        AVObject.saveAllInBackground(avObjectList).subscribe()

    }

    private fun initAdapter() {
        val layoutManager = LinearLayoutManager(this)
        binding.rvDotActTablet.apply {
            this.layoutManager = layoutManager
            this.addItemDecoration(
                DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
            )
            this.setSwipeMenuCreator { _, rightMenu, _ ->
                val deleteItem = SwipeMenuItem(context)
                deleteItem.setBackgroundColor(Color.parseColor("#FF3D39"))
                    .setText("删除")
                    .setTextColor(Color.WHITE)
                    .setHeight(ViewGroup.LayoutParams.MATCH_PARENT).width = 170
                rightMenu.addMenuItem(deleteItem)
            }
            this.setOnItemMenuClickListener { menuBridge, adapterPosition ->
                menuBridge.closeMenu()
                //dotDao.deleteDot(dotList[adapterPosition])
                dotList.removeAt(adapterPosition)
                dotAdapter.notifyDataSetChanged()
            }
            this.adapter = dotAdapter
        }

    }

    private fun initData(tabletId: Long) {
        thread {
            tablet = tabletDao.loadTabletById(tabletId)!!
            for (dot in dotDao.loadDotsInTablet(tabletId)) {
                dotList.add(dot)
            }
            dotAdapter.notifyDataSetChanged()

            runOnUiThread {
                initView(tablet)
            }
        }
    }

    private fun writeInputStreamToFile() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            "You must use device running Android 10 or higher".showToast()
            return
        }
        thread {
            try {
                val values = ContentValues()
                values.put(MediaStore.MediaColumns.DISPLAY_NAME, "${tablet.id}${tablet.place}${tablet.date}.txt")
                values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
                val uri = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
                if (uri != null) {
                    val outputStream = contentResolver.openOutputStream(uri)
                    if (outputStream != null) {
                        val bos = BufferedOutputStream(outputStream)
                        //val buffer = ByteArray(1024)
                        for(dot in dotList){
                            val data = (dot.toString()+"\r\n").toByteArray()
                            bos.write(data, 0, data.size)
                        }
                        bos.flush()
                        bos.close()
                    }
                }
                shareFile(this, uri)

            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }


    private fun shareFile(context: Context, fileUri: Uri?): Boolean {
        if (fileUri != null) {
            val share = Intent(Intent.ACTION_SEND)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                share.putExtra(Intent.EXTRA_STREAM, fileUri)
                share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            } else {
                share.putExtra(Intent.EXTRA_STREAM, fileUri)
            }
            share.type = "text/plain" //此处可发送多种文件
            share.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            context.startActivity(Intent.createChooser(share, "分享文件"))
        } else {
            Toast.makeText(context, "分享文件不存在", Toast.LENGTH_SHORT).show()
            return false
        }
        return true
    }
}